package com.example.petchating.collision

import com.badlogic.gdx.graphics.glutils.ShapeRenderer
import com.badlogic.gdx.maps.objects.RectangleMapObject
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer
import com.badlogic.gdx.math.Rectangle
import com.example.petchating.map.MapLoader

class CollisionManager(private val mapLoader: MapLoader) {
    val map = mapLoader.map
    // 存储所有碰撞矩形（来自对象层和图块属性）
     val collisionRectangles = mutableListOf<Rectangle>()
    // 存储图块ID到碰撞形状的映射
     val tileCollisionShapes = mutableMapOf<Int, List<Rectangle>>()

    private val shapeRenderer = ShapeRenderer()

    init {
        extractCollisionData()
    }

    /** 从地图中提取所有碰撞数据（对象层和图块属性） */
    private fun extractCollisionData() {
        // 1. 从对象层提取碰撞矩形
        map.layers.forEach { layer ->
            if (layer.name.contains("collision", ignoreCase = true)) {
                layer.objects.forEach { mapObject ->
                    if (mapObject is RectangleMapObject) {
                        collisionRectangles.add(mapObject.rectangle)
                    }
                }
            }
        }

        // 2. 从图块集提取自定义碰撞形状
        map.tileSets.forEach { tileSet -> //遍历图块集
            val tiles = tileSet.iterator() // 获取图块集迭代器
            while(tiles.hasNext()) {// 遍历图块
                val tile = tiles.next()
                if(tile!=null){ //图块集可能是从更大的图像中切割而来，部分区域未被使用，因此 Tiled 允许图块集存在 “空洞”（即某些索引位置没有图块）
                    val collisionShapes = mutableListOf<Rectangle>()//存储该图块对应的所有碰撞矩形（一个图块可能有多个碰撞区域）
                    // 检查图块是否有自定义碰撞对象
                    tile.objects?.forEach { obj ->
                        if (obj is RectangleMapObject) {
                            collisionShapes.add(obj.rectangle)
                        }
                    }
                    if (collisionShapes.isNotEmpty()) {
                        tileCollisionShapes[tile.id] = collisionShapes //tile.id为图块在地图的全局id
                    }
                }
            }
        }
    }

    /** 检查角色是否与地图碰撞 */
    fun checkCollision(newX: Float, newY: Float, petBounds: Rectangle):  Boolean{
        // 计算角色移动后的新边界
        val newBounds = petBounds
        newBounds.x = newX
        newBounds.y = newY

        // 1. 检查与对象层碰撞矩形的碰撞
        if(!collisionRectangles.isEmpty())
        {
            for (rect in collisionRectangles) {
                if (newBounds.overlaps(rect)) {
                    return true
                }
            }
        }

        // 2. 检查与图块的碰撞（优化版：只检查角色周围的图块）
        // 计算角色旁边的图块的图块/单元格坐标
        val startX = Math.max(0, (newBounds.x / mapLoader.tileWidth).toInt() - 1)
        val endX = Math.min((mapLoader.mapWidth).toInt() - 1, ((newBounds.x + newBounds.width) / mapLoader.tileWidth).toInt() + 1)
        val startY = Math.max(0, (newBounds.y / mapLoader.mapHeight).toInt() - 1)
        val endY = Math.min((mapLoader.mapHeight).toInt() - 1, ((newBounds.y + newBounds.height) / mapLoader.tileHeight).toInt() + 1)

        // 遍历角色周围的图块
        for (layer in map.layers) {
            if (layer is TiledMapTileLayer) {//只遍历图块层
                for (x in startX..endX) {
                    for (y in startY..endY) {
                        val cell = layer.getCell(x, y) ?: continue //根据单元格坐标获取图块
                        val tile = cell.tile ?: continue

                        // 检查该图块是否有碰撞形状
                        if (tileCollisionShapes.containsKey(tile.id)) {
                            // 计算图块在世界坐标系中的位置
                            val tileWorldX = x * mapLoader.tileWidth
                            val tileWorldY = y * mapLoader.tileHeight

                            // 检查角色与该图块的所有碰撞形状
                            for (shape in tileCollisionShapes.getValue(tile.id)) {
                                // 创建图块碰撞形状的世界坐标版本
                                val worldShape = Rectangle(
                                    tileWorldX + shape.x,
                                    tileWorldY + shape.y,
                                    shape.width,
                                    shape.height
                                )

                                if (newBounds.overlaps(worldShape)) {
                                    return true
                                }
                            }
                        }
                    }
                }
            }
        }

        return false
    }
    //渲染碰撞边界
//    fun render(character: Pet) {
//        shapeRenderer.begin(ShapeRenderer.ShapeType.Line)
//
//        // 1. 绘制角色边界
//        shapeRenderer.color = Color.GREEN
//        val bounds = character.collisionBounds
//        shapeRenderer.rect(bounds.x, bounds.y, bounds.width, bounds.height)
//
//        // 2. 绘制碰撞检测范围
//        shapeRenderer.color = Color.YELLOW
//
//        // 计算与checkCollision方法中相同的检测范围
//        val newBounds = Rectangle(bounds)
//        val deltaX = 0f // 假设没有移动
//        val deltaY = 0f // 假设没有移动
//        newBounds.x += deltaX
//        newBounds.y += deltaY
//
//        val startX = Math.max(0, (newBounds.x / map.tileWidth).toInt() - 1)
//        val endX = Math.min(map.width - 1, ((newBounds.x + newBounds.width) / map.tileWidth).toInt() + 6)
//        val startY = Math.max(0, (newBounds.y / map.tileHeight).toInt() - 1)
//        val endY = Math.min(map.height - 1, ((newBounds.y + newBounds.height) / map.tileHeight).toInt() + 6)
//
//        // 绘制检测范围的边界框
//        val rangeX = startX * map.tileWidth
//        val rangeY = startY * map.tileHeight
//        val rangeWidth = (endX - startX + 1) * map.tileWidth
//        val rangeHeight = (endY - startY + 1) * map.tileHeight
//
//        shapeRenderer.rect(rangeX.toFloat(), rangeY.toFloat(), rangeWidth.toFloat(), rangeHeight.toFloat())
//
//
//
//        // 3. 绘制所有碰撞形状
//        shapeRenderer.color = Color.RED
//
//        if(!collisionRectangles.isEmpty())
//        {
//            for (worldShape in collisionRectangles) {
//                shapeRenderer.rect(worldShape.x, worldShape.y, worldShape.width, worldShape.height)
//            }
//        }
//        for (layer in map.layers) {
//            if (layer is TiledMapTileLayer) {
//                for (x in startX..endX) {
//                    for (y in startY..endY) {
//                        val cell = layer.getCell(x, y) ?: continue
//                        val tile = cell.tile ?: continue
//
//                        if (tileCollisionShapes.containsKey(tile.id)) {
//                            val tileWorldX = x * map.tileWidth
//                            val tileWorldY = y * map.tileHeight
//
//                            for (shape in tileCollisionShapes.getValue(tile.id)) {
//                                val worldShape = Rectangle(
//                                    tileWorldX + shape.x,
//                                    tileWorldY + shape.y,
//                                    shape.width,
//                                    shape.height
//                                )
//
//                                shapeRenderer.rect(worldShape.x, worldShape.y, worldShape.width, worldShape.height)
//                            }
//                        }
//                    }
//                }
//            }
//        }
//
//        shapeRenderer.end()
//    }
}
